#include "ObjectManager.h"

ObjectManager::ObjectManager(b2World *gameWorld)
{
	this->gameWorld = gameWorld;
}

ObjectManager::~ObjectManager()
{
	clearActiveObjects();
}

void ObjectManager::addBox(b2Vec2 size, b2Vec2 location, BodyType bodyType, float density, float friction, sf::Color rectColor)
{
	bool active = false;
	RectEntity *newRect = new RectEntity;

	b2BodyDef bodyDef;
	if(bodyType == DYNAMIC_BODY)
	{
		bodyDef.type = b2_dynamicBody;
		bodyDef.position.Set(location.x, location.y);
		bodyDef.angularDamping = .01f;
		bodyDef.allowSleep = true;
		active = true;
	}
	else if(bodyType == STATIC_BODY)
	{
		bodyDef.type = b2_staticBody;
		bodyDef.position.Set(location.x - ((int)location.x % (int)size.x) + size.x / 2, location.y - ((int)location.y % (int)size.y) - size.y / 2);
		bodyDef.allowSleep = false;
		active = false;
	}
	newRect->rectBody = gameWorld->CreateBody(&bodyDef);
	//newRect->rectBody->SetFixedRotation(false);
	b2PolygonShape dynamicBox;
	dynamicBox.SetAsBox(size.x / 2, size.y / 2);
	b2FixtureDef fixtureDef;
	fixtureDef.shape = &dynamicBox;
	fixtureDef.density = density;
	fixtureDef.friction = friction;
	fixtureDef.restitution = .5f;
	newRect->rectBody->CreateFixture(&fixtureDef);

	b2Vec2 position = newRect->rectBody->GetPosition();
	float angle = newRect->rectBody->GetAngle();

	
	//newRect->rectShape.setPosition(position.x, position.y);
	//newRect->rectShape.setRotation(angle);
	newRect->rectShape.setSize(sf::Vector2f(size.x, size.y));
	newRect->rectShape.setOrigin(size.x / 2, size.y / 2);
	newRect->rectShape.setOutlineThickness(.8f);
	newRect->rectShape.setOutlineColor(sf::Color(30, 30, 30, 255));
	newRect->rectShape.setFillColor(rectColor);

	//if(active)
		activeRectList.push_back(newRect);
	//else if (!active)
	//	inactiveRectList.push_back(newRect);

}

void ObjectManager::addCircle(float radius, b2Vec2 location, BodyType bodyType, float density, float friction, sf::Color rectColor)
{
	bool active = false;
	CircleEntity *newCircle = new CircleEntity;

	b2BodyDef bodyDef;
	if(bodyType == DYNAMIC_BODY)
	{
		bodyDef.type = b2_dynamicBody;
		bodyDef.position.Set(location.x, location.y);
		bodyDef.angularDamping = .01f;
		bodyDef.allowSleep = true;
		active = true;
	}

	newCircle->circleBody = gameWorld->CreateBody(&bodyDef);
	//newRect->rectBody->SetFixedRotation(false);
	b2CircleShape dynamicCircle;
	dynamicCircle.m_radius = radius;
	
	b2FixtureDef fixtureDef;
	fixtureDef.shape = &dynamicCircle;
	fixtureDef.density = density;
	fixtureDef.friction = friction;
	newCircle->circleBody->CreateFixture(&fixtureDef);
	newCircle->circleBody->SetBullet(true);

	b2Vec2 position = newCircle->circleBody->GetPosition();
	float angle = newCircle->circleBody->GetAngle();

	newCircle->circleShape.setOrigin(radius, radius);
	newCircle->circleShape.setRadius(radius);
	newCircle->circleShape.setOutlineThickness(.8f);
	newCircle->circleShape.setOutlineColor(sf::Color(30, 30, 30, 255));
	newCircle->circleShape.setFillColor(rectColor);

	//if(active)
		activeCircleList.push_back(newCircle);
}
void ObjectManager::addGround(float depth, float length)
{
	b2BodyDef groundBodyDef;
	groundBodyDef.type = b2_staticBody;
	groundBodyDef.position.Set(0.0f, depth);
	ground.groundBody = gameWorld->CreateBody(&groundBodyDef);
	b2PolygonShape groundBox;
	groundBox.SetAsBox(length, 3.0f);
	ground.groundBody->CreateFixture(&groundBox, 0.0f);

	b2FixtureDef fixtureDef;
	fixtureDef.shape = &groundBox;
	fixtureDef.density = 1;
	fixtureDef.friction = 1;
	fixtureDef.restitution = .5f;

	ground.groundShape.resize(2);
	ground.groundShape.setPrimitiveType(sf::PrimitiveType::Lines);
	ground.groundShape[0].position = sf::Vector2f(0, -depth);
	ground.groundShape[1].position = sf::Vector2f(length, -depth);
}

void ObjectManager::clearObjects()
{
	clearActiveObjects();
}

std::vector<RectEntity*> ObjectManager::getActiveRectList()
{
	return activeRectList;
}

std::vector<CircleEntity*> ObjectManager::getActiveCircleList()
{
	return activeCircleList;
}


GroundEntity ObjectManager::getGround()
{
	return ground;
}

//////////PRIVATE FUNCTIONS//////////////////////////////////////////////

void ObjectManager::clearActiveObjects()
{
	for(int i = activeRectList.size() - 1; i >= 0; i--)
	{
		gameWorld->DestroyBody(activeRectList.at(i)->rectBody);
		delete activeRectList.at(i);
		activeRectList.pop_back();
	}
}
